#include "stdafx.h"
/* Copyright (C) Noel Llopis, 2001. 
 * All rights reserved worldwide.
 *
 * This software is provided "as is" without express or implied
 * warranties. You may freely copy and compile this source into
 * applications you distribute provided that the copyright text
 * below is included in the resulting source code, for example:
 * "Portions Copyright (C) Noel Llopis, 2001"
 */
//-----------------------------------------------------------------------------
//
//  DeprecationManager.cpp
//
//      See DeprecationManager.h for a detailed description of this class.
//
//      Noel Llopis  --  11/20/2000
//
//-----------------------------------------------------------------------------

#include "Deprecation.h"
#include <windows.h>


NotImplementedManager::NotImplementedManager ( void )
{
}


NotImplementedManager::~NotImplementedManager ( void )
{
	if ( !m_Functions.empty() )
	{
		OutputDebugStringA( "*************************************************************\n" );
		OutputDebugStringA( "WARNING. You are using the following not implemented functions:\n" );

		char txt[255];
		std::map<const char *, NotImplementedFunction>::iterator i;
		for ( i=m_Functions.begin(); i!=m_Functions.end(); ++i )
		{
			NotImplementedFunction * pFunction = &((*i).second);

			sprintf_s( txt, "- Function %s called from %i different places.\n",
							pFunction->FunctionName, 
							pFunction->CalledFrom.size() );
			OutputDebugStringA (txt);
		}


		OutputDebugStringA( "*************************************************************\n" );

		m_Functions.clear();
	}
}


NotImplementedManager * NotImplementedManager::GetInstance ( void )
{
	static NotImplementedManager Instance;
	return &Instance;
}


bool NotImplementedManager::AddNotImplementedFunction ( const char * FunctionName, 
														const void * FramePtr )
{
	bool bAddedForFirstTime = false;

	int *pReturn = (int*)FramePtr+1; // usual return address @ [ebp+4]

	int CalledFrom = IsBadReadPtr( pReturn,4 ) ? 0 : *pReturn;

	// Check if this function was already listed as deprecated
	std::map<const char *, NotImplementedFunction>::iterator ExistingFunc;
	ExistingFunc = m_Functions.find (FunctionName);

	// If it wasn't, make a new entry for it
	if ( ExistingFunc == m_Functions.end() )
	{
		NotImplementedFunction Function;
		Function.FunctionName = FunctionName;
		Function.CalledFrom.insert ( CalledFrom );

		m_Functions[FunctionName] = Function;
		bAddedForFirstTime = true;
	}

	// If it was, keep track of where it's called from
	else
	{
		// Since we're keeping track of the addresses this function
		// was called from in a set, we don't need to check whether we've
		// already added the address.
		NotImplementedFunction * pFunction = &((*ExistingFunc).second);
		pFunction->CalledFrom.insert ( CalledFrom );
	}

	return bAddedForFirstTime;
}

DeprecationManager::DeprecationManager ( void )
{
}


DeprecationManager::~DeprecationManager ( void )
{
	if ( !m_Functions.empty() )
	{
		OutputDebugStringA( "*************************************************************\n" );
		OutputDebugStringA( "WARNING. You are using the following deprecated functions:\n" );

		char txt[255];
		std::map<const char *, DeprecatedFunction>::iterator i;
		for ( i=m_Functions.begin(); i!=m_Functions.end(); ++i )
		{
			DeprecatedFunction * pFunction = &((*i).second);

			sprintf_s( txt, "- Function %s called from %i different places.\n",
							pFunction->OldFunctionName, 
							pFunction->CalledFrom.size() );
			OutputDebugStringA (txt);

			sprintf_s( txt, "  Instead use %s.\n", 
							pFunction->NewFunctionName );
			OutputDebugStringA (txt);
		}


		OutputDebugStringA( "*************************************************************\n" );

		m_Functions.clear();
	}
}


DeprecationManager * DeprecationManager::GetInstance ( void )
{
	static DeprecationManager Instance;
	return &Instance;
}


bool DeprecationManager::AddDeprecatedFunction ( const char * OldFunctionName, 
											 const char * NewFunctionName,
											 const void * FramePtr )
{
	bool bAddedForFirstTime = false;

	int *pReturn = (int*)FramePtr+1; // usual return address @ [ebp+4]

	int CalledFrom = IsBadReadPtr( pReturn,4 ) ? 0 : *pReturn;

	// Check if this function was already listed as deprecated
	std::map<const char *, DeprecatedFunction>::iterator ExistingFunc;
	ExistingFunc = m_Functions.find (OldFunctionName);

	// If it wasn't, make a new entry for it
	if ( ExistingFunc == m_Functions.end() )
	{
		DeprecatedFunction Function;
		Function.OldFunctionName = OldFunctionName;
		Function.NewFunctionName = NewFunctionName;
		Function.CalledFrom.insert ( CalledFrom );

		m_Functions[OldFunctionName] = Function;
		bAddedForFirstTime = true;
	}

	// If it was, keep track of where it's called from
	else
	{
		// Since we're keeping track of the addresses this function
		// was called from in a set, we don't need to check whether we've
		// already added the address.
		DeprecatedFunction * pFunction = &((*ExistingFunc).second);
		pFunction->CalledFrom.insert ( CalledFrom );
	}

	return bAddedForFirstTime;
}
